module.exports = BinaryWriter

function BinaryWriter(size, allowResize) {
  this.buffer = new Buffer(size)
  this.position = 0
  this.allowResize = allowResize
}

function _write(write, size) {
  return function(value, noAssert) {
    this.ensureSize(size)

    write.call(this.buffer, value, this.position, noAssert)
    this.position += size
  }
}

BinaryWriter.prototype.writeUInt8 = _write(Buffer.prototype.writeUInt8, 1)
BinaryWriter.prototype.writeUInt16LE = _write(Buffer.prototype.writeUInt16LE, 2)
BinaryWriter.prototype.writeUInt16BE = _write(Buffer.prototype.writeUInt16BE, 2)
BinaryWriter.prototype.writeUInt32LE = _write(Buffer.prototype.writeUInt32LE, 4)
BinaryWriter.prototype.writeUInt32BE = _write(Buffer.prototype.writeUInt32BE, 4)
BinaryWriter.prototype.writeInt8 = _write(Buffer.prototype.writeInt8, 1)
BinaryWriter.prototype.writeInt16LE = _write(Buffer.prototype.writeInt16LE, 2)
BinaryWriter.prototype.writeInt16BE = _write(Buffer.prototype.writeInt16BE, 2)
BinaryWriter.prototype.writeInt32LE = _write(Buffer.prototype.writeInt32LE, 4)
BinaryWriter.prototype.writeInt32BE = _write(Buffer.prototype.writeInt32BE, 4)
BinaryWriter.prototype.writeFloatLE = _write(Buffer.prototype.writeFloatLE, 4)
BinaryWriter.prototype.writeFloatBE = _write(Buffer.prototype.writeFloatBE, 4)
BinaryWriter.prototype.writeDoubleLE = _write(Buffer.prototype.writeDoubleLE, 8)
BinaryWriter.prototype.writeDoubleBE = _write(Buffer.prototype.writeDoubleBE, 8)

BinaryWriter.prototype.writeBuffer = function(buffer) {
  this.ensureSize(buffer.length)

  buffer.copy(this.buffer, this.position, 0, buffer.length)
  this.position += buffer.length
}

BinaryWriter.prototype.writeVarInt = function(value) {
  var length = 1

  while ((value & 0xFFFFFF80) !== 0) {
    this.writeUInt8((value & 0x7F) | 0x80)
    value >>>= 7
    length++
  }

  this.writeUInt8(value & 0x7F)

  return length
}

BinaryWriter.prototype.ensureSize = function(size) {
  if (this.buffer.length < this.position + size) {
    if (this.allowResize) {
      var tempBuffer = new Buffer(this.position + size)
      this.buffer.copy(tempBuffer, 0, 0, this.buffer.length)
      this.buffer = tempBuffer
    } else {
      throw new RangeError('index out of range')
    }
  }
}
